import ast
import os
import requests
import datetime
import uuid
import shutil
import time
import json
from typing import List
import uvicorn
import asyncio
import argparse
import torch
from fastapi import FastAPI, HTTPException, Request, File, UploadFile, Form
from logs.log import setup_custom_logger
from fastapi.middleware.cors import CORSMiddleware
from logs.log_middleware import LogMiddleware
from pydantic import BaseModel
from utils.HashUtil import HashUtil
from utils.qwen_infer_utils import qwen2ForOpenAI
from utils.qwen_infer_v2_utils import qwen2ForOpenAIv2


# 日志系统初始化3
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
LOG_DIR = './logfiles'
# 确保日志目录存在

file_name = str(datetime.datetime.now().strftime('%Y-%m-%d'))
my_logger = setup_custom_logger(os.path.join(LOG_DIR, '%s.log' % file_name), log_level="INFO") # type: ignore

app = FastAPI()
app.add_middleware(LogMiddleware)

app.add_middleware(CORSMiddleware,
                   allow_origins=["*"],
                   allow_credentials=True,
                   allow_methods=["*"],
                   allow_headers=["*"]
                   )

# 模型初始化
template_prompt_path = "./configs/prompt_template.txt"
client = qwen2ForOpenAI(template_path=template_prompt_path, model_name="xiaoxingv2")

template_prompt_path2 = "./configs/prompt_template_0812.txt"
client2 = qwen2ForOpenAIv2(template_path=template_prompt_path, model_name="xiaoxingv3")


@app.get("/intention")
async def root():
    return {"message": "welcome!"}


class Item(BaseModel):
    start: float
    end: float
    text: str


class ReqData(BaseModel):
    kndata: List[str]
    transcript: List[Item]


class ReqDataStrs(BaseModel):
    rqAppId: str
    rqMsg: str
    rqTime: int
    rqSign: str


class RespData(BaseModel):
    code: int
    intent: str
    slots: str
    source: str
    message: str


async def writesrt(data: List[Item], savePath: str):
    with open(savePath, 'w', encoding='utf-8') as f:
        for i in range(len(data)):
            start = data[i].start
            end = data[i].end
            text = data[i].text
            f.write(str(i) + '\n')
            f.write(str(start) + ' --> ' + str(end) + '\n')
            f.write(text + '\n')


def errorResponse(msg: str):
    response = RespData(
        code=0,
        intent="",
        slots="",
        source="",
        message=msg
    )
    return response


@app.post("/llmintention/api/identify/v3")
async def xiaoxingintention(data: ReqDataStrs): # type: ignore
    request_id = str(uuid.uuid4())
    rqAppId = data.rqAppId
    rqTime = data.rqTime
    rqSign = data.rqSign
    rqMsg = data.rqMsg

    isOk = 0
    response = "error"
    intentOuter = ""
    slotsOuter = ""
    sourceOuter = ""
    #    save_path = os.path.join("uploaded_files", file_name)
    try:
        print("hello test")
        appSecret = HashUtil.getAppIdKey(rqAppId) # type: ignore
        if appSecret == '':
            return errorResponse("非法密钥")

        preSignStr = appSecret + rqMsg + str(rqTime) # type: ignore
        # my_logger.info(preSignStr)
        signStr = HashUtil.sha256_hash(preSignStr) # type: ignore
        my_logger.info(signStr)
        if signStr != rqSign:
            message = "校验失败"
            my_logger.error("校验失败")
        else:
            now = datetime.datetime.now()
            milliseconds = int(now.timestamp() * 1000)
            if milliseconds - rqTime < 5 * 60 * 1000:
                isOk = 1
                my_logger.info(rqMsg)
                intent = client2.classify(rqMsg)
                prob = ""
                slots = ""
                my_logger.info(intent)
                intentOuter = intent
                slotsOuter = slots
                sourceOuter = prob
                my_logger.info(slotsOuter)
            else:
                message = "请求超期"
                my_logger.error(f"{message}")
                return {"code":"-1", "message": message}

        sw = ""
        if slotsOuter:
            data = ast.literal_eval(slotsOuter)
            if isinstance(data, list) and data:
                arrays = data[0]
                if isinstance(arrays, tuple) and len(arrays) > 1:
                    sw = arrays[1]
        my_logger.info(f"intentOuter:{intentOuter}")
        intentstr = intentOuter
        response = "cla_id=" + intentstr + "&cla_name=" + intentstr + "&data={\"action\":1,\"sw\":\"" + sw + "\"}"
        # if intentOuter == "resource":
            # response = "internt=" + intentOuter + "&data={\"url\":\"https://literaturesearch.mh.chaoxing.com/multi-search\"}" + "&sw=" + sw + "&author=&channel=&time=&jg="
    except Exception as e:
        my_logger.error(f"{request_id} 匹配失败，错误信息：{e}")
        # raise HTTPException(status_code=500, detail="获取匹配结果失败！！！")
        message = "请求异常"
        return {"code": -1, "message": message}
        # return message
    return response


@app.post("/llmintention/api/identify/v2")
async def match_nlp(data: ReqDataStrs): # type: ignore
    request_id = str(uuid.uuid4())
    rqAppId = data.rqAppId
    rqTime = data.rqTime
    rqSign = data.rqSign
    rqMsg = data.rqMsg

    isOk = 0
    response = "error"
    intentOuter = ""
    slotsOuter = ""
    sourceOuter = ""
    #    save_path = os.path.join("uploaded_files", file_name)
    try:
        print("hello test")
        appSecret = HashUtil.getAppIdKey(rqAppId) # type: ignore
        if appSecret == '':
            return errorResponse("非法密钥")

        preSignStr = appSecret + rqMsg + str(rqTime) # type: ignore
        # my_logger.info(preSignStr)
        signStr = HashUtil.sha256_hash(preSignStr) # type: ignore
        my_logger.info(signStr)
        if signStr != rqSign:
            message = "校验失败"
            my_logger.error("校验失败")
        else:
            now = datetime.datetime.now()
            milliseconds = int(now.timestamp() * 1000)
            if milliseconds - rqTime < 5 * 60 * 1000:
                isOk = 1
                my_logger.info(rqMsg)
                intent = client.classify(rqMsg)
                prob = ""
                slots = ""
                my_logger.info(intent)
                intentOuter = intent
                slotsOuter = slots
                sourceOuter = prob
                my_logger.info(slotsOuter)
            else:
                message = "请求超期"
                my_logger.error(f"{message}")
                return {"code":"-1", "message": message}

        sw = ""
        if slotsOuter:
            data = ast.literal_eval(slotsOuter)
            if isinstance(data, list) and data:
                arrays = data[0]
                if isinstance(arrays, tuple) and len(arrays) > 1:
                    sw = arrays[1]
        my_logger.info(f"intentOuter:{intentOuter}")
        intentstr = intentOuter
        response = "cla_id=" + intentstr + "&cla_name=" + intentstr + "&data={\"action\":1,\"sw\":\"" + sw + "\"}"
        # if intentOuter == "resource":
            # response = "internt=" + intentOuter + "&data={\"url\":\"https://literaturesearch.mh.chaoxing.com/multi-search\"}" + "&sw=" + sw + "&author=&channel=&time=&jg="
    except Exception as e:
        my_logger.error(f"{request_id} 匹配失败，错误信息：{e}")
        # raise HTTPException(status_code=500, detail="获取匹配结果失败！！！")
        message = "请求异常"
        return {"code": -1, "message": message}
        # return message
    return response



# 唯一区别在于，本方式用于校验加密，不做大模型数据的调用
@app.post("/llmintention/api/identify/hello")
async def match_nlp(data: ReqDataStrs):
    request_id = str(uuid.uuid4())
    rqAppId = data.rqAppId
    rqTime = data.rqTime
    rqSign = data.rqSign
    rqMsg = data.rqMsg

    isOk = 0
    message = "请求成功"
    intentOuter = ""
    slotsOuter = ""
    sourceOuter = ""
    #    save_path = os.path.join("uploaded_files", file_name)
    try:
        appSecret = HashUtil.getAppIdKey(rqAppId) # type: ignore
        if appSecret == '':
            return errorResponse("非法密钥")

        preSignStr = appSecret + rqMsg + str(rqTime) # type: ignore
        my_logger.info(preSignStr)
        signStr = HashUtil.sha256_hash(preSignStr) # type: ignore
        my_logger.info(signStr)
        if signStr != rqSign:
            message = "校验失败"
        else:
            now = datetime.datetime.now()
            milliseconds = int(now.timestamp() * 1000)
            if milliseconds - rqTime < 5 * 60 * 1000:
                isOk = 1
            else:
                message = "请求超期"

    except Exception as e:
        my_logger.error(f"{request_id} 匹配失败，错误信息：{e}")
        # raise HTTPException(status_code=500, detail="获取匹配结果失败！！！")
        message = "请求异常"

    response = RespData(
        code=isOk,
        intent=intentOuter,
        slots=slotsOuter,
        source=sourceOuter,
        message=message
    )
    return response


if __name__ == "__main__":
    if not os.path.exists(LOG_DIR):
        os.makedirs(LOG_DIR)
    uvicorn.run("main:app", workers=1, limit_concurrency=200, limit_max_requests=10000,
                host="0.0.0.0", port=8099)
